package com.ms.pda.utils.frid

import android.Manifest
import android.app.Activity
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Handler
import android.os.Message
import android.text.TextUtils
import android.util.Log
import androidx.core.app.ActivityCompat
import com.blankj.utilcode.util.GsonUtils
import com.blankj.utilcode.util.SPUtils
import com.blankj.utilcode.util.ToastUtils
import com.google.gson.Gson
import com.ms.pda.R
import com.ms.pda.model.Constants
import com.rscja.deviceapi.RFIDWithUHFBLE
import com.rscja.deviceapi.interfaces.ConnectionStatus
import com.rscja.deviceapi.interfaces.ConnectionStatusCallback
import java.util.Timer
import java.util.TimerTask

/**
 * @Package: com.ms.pda.utils.frid
 * @Description: java类作用描述
 * @Author: ldy
 * @CreateDate: 2023/11/1 11:30
 */
class CWFridManager(activity: Activity?, onRfidEventsListener: OnRfidEventsListener?) :
    BaseFridManager(activity, onRfidEventsListener) {
    companion object {
        private const val TAG = "CWFridManager"

        public const val SHOW_HISTORY_CONNECTED_LIST = "showHistoryConnectedList"
        public const val TAG_DATA = "tagData"
        public const val TAG_EPC = "tagEpc"
        public const val TAG_TID = "tagTid"
        public const val TAG_USER = "tagUser"
        public const val TAG_LEN = "tagLen"
        public const val TAG_COUNT = "tagCount"
        public const val TAG_RSSI = "tagRssi"
    }


    var remoteBTName = ""
    var remoteBTAdd = ""
    private val REQUEST_ENABLE_BT = 2
    private val REQUEST_SELECT_DEVICE = 1
    var tagList: ArrayList<HashMap<String, String>>? = null
    public var selectEPC: String? = null
    var isSupportRssi = false
    public val uhf: RFIDWithUHFBLE = RFIDWithUHFBLE.getInstance()
    public var isScanning = false
    var mDevice: BluetoothDevice? = null
    var mBtAdapter: BluetoothAdapter? = null

    var btStatus = BTStatus()


    private var mIsActiveDisconnect = true // 是否主动断开连接

    private val RECONNECT_NUM = Int.MAX_VALUE // 重连次数

    private var mReConnectCount = RECONNECT_NUM // 重新连接次数


    private val mDisconnectTimer = Timer()
    private var timerTask: DisconnectTimerTask? = null
    private var timeCountCur: Long = 0 // 断开时间选择

    private val period = (1000 * 30 // 隔多少时间更新一次
            ).toLong()
    private val lastTouchTime = System.currentTimeMillis() // 上次接触屏幕操作的时间戳

    var isKeyDownUP = false
    private val RUNNING_DISCONNECT_TIMER = 10
    private val mHandler: Handler = object : Handler() {
        override fun handleMessage(msg: Message) {
            when (msg.what) {
                RUNNING_DISCONNECT_TIMER -> {
                    val time = msg.obj as Long
                    formatConnectButton(time)
                }
            }
        }
    }


    init {
        uhf.init(activity!!.applicationContext)
    }

    override fun connect() {

    }

    override fun onDestroy() {

    }

    /**
     * 重置断开时间
     */
    fun resetDisconnectTime() {
        timeCountCur = SPUtils.getInstance()
            .getLong(Constants.DISCONNECT_TIME, 0)
        if (timeCountCur > 0) {
            formatConnectButton(timeCountCur)
        }
    }

    private fun formatConnectButton(disconnectTime: Long) {
        val buttonText = if (uhf.connectStatus == ConnectionStatus.CONNECTED) {
            if (!isScanning && System.currentTimeMillis() - lastTouchTime > 1000 * 30 && timerTask != null) {
                val minute = disconnectTime / 1000 / 60
                if (minute > 0) {
                    activity?.getString(R.string.disConnectForMinute, minute)//倒计时分
                } else {
                    activity?.getString(R.string.disConnectForSecond, disconnectTime / 1000)//倒计时秒
                }
            } else {
                activity?.getString(R.string.disConnect)
            }
        } else {
            activity?.getString(R.string.Connect)
        }
        Log.e(TAG, "formatConnectButton buttonText = $buttonText")
    }

    private fun showBluetoothDevice(isHistory: Boolean) {
        if (mBtAdapter == null) {
            ToastUtils.showShort("Bluetooth is not available")
            return
        }
        if (!mBtAdapter!!.isEnabled) {
            Log.i(TAG, "onClick - BT not enabled yet")
            val enableIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
            if (ActivityCompat.checkSelfPermission(
                    activity!!,
                    Manifest.permission.BLUETOOTH_CONNECT
                ) == PackageManager.PERMISSION_GRANTED
            ) {
                activity?.startActivityForResult(enableIntent, REQUEST_ENABLE_BT)
            } else {

            }

        } else {
//            val newIntent = Intent(activity, DeviceListActivity::class.java)
//            newIntent.putExtra(SHOW_HISTORY_CONNECTED_LIST, isHistory)
//            activity?.startActivityForResult(newIntent, REQUEST_SELECT_DEVICE)
//            cancelDisconnectTimer()
        }
    }

    fun connect(deviceAddress: String?) {
        if (uhf.connectStatus == ConnectionStatus.CONNECTING) {
            ToastUtils.showShort(R.string.connecting)
        } else {
            uhf.connect(deviceAddress, btStatus)
        }
    }

    fun disconnect(isActiveDisconnect: Boolean) {
        cancelDisconnectTimer()
        mIsActiveDisconnect = isActiveDisconnect // 主动断开为true
        uhf.disconnect()
    }

    /**
     * 重新连接
     *
     * @param deviceAddress
     */
    private fun reConnect(deviceAddress: String) {
        if (!mIsActiveDisconnect && mReConnectCount > 0) {
            connect(deviceAddress)
            mReConnectCount--
        }
    }

    /**
     * 应该提示未连接状态
     *
     * @return
     */
    private fun shouldShowDisconnected(): Boolean {
        return mIsActiveDisconnect || mReConnectCount == 0
    }

    fun saveConnectedDevice(address: String, name: String) {
        val string = SPUtils.getInstance().getString(Constants.CONNECTED_DEVICE, null)
        val map: HashMap<String, String> = hashMapOf()
        if (!string.isNullOrEmpty()) {
            map.putAll(GsonUtils.fromJson<HashMap<String, String>>(string, HashMap::class.java))
        }
        map[address] = name
        SPUtils.getInstance().put(Constants.CONNECTED_DEVICE, GsonUtils.toJson(map))
    }

    fun updateConnectMessage(oldName: String?, newName: String) {
        if (!TextUtils.isEmpty(oldName) && !TextUtils.isEmpty(newName)) {
            remoteBTName = newName
        }
    }

    //------------连接状态监听-----------------------
    private val connectStatusList: MutableList<IConnectStatus> = java.util.ArrayList()

    fun addConnectStatusNotice(iConnectStatus: IConnectStatus) {
        connectStatusList.add(iConnectStatus)
    }

    fun removeConnectStatusNotice(iConnectStatus: IConnectStatus) {
        connectStatusList.remove(iConnectStatus)
    }

    private fun startDisconnectTimer(time: Long) {
        timeCountCur = time
        timerTask = DisconnectTimerTask()
        mDisconnectTimer.schedule(timerTask, 0, period)
    }

    fun cancelDisconnectTimer() {
        timeCountCur = 0
        timerTask?.cancel()
        timerTask = null
    }

    interface IConnectStatus {
        fun getStatus(connectionStatus: ConnectionStatus?)
    }

    inner class BTStatus : ConnectionStatusCallback<Any?> {
        override fun getStatus(connectionStatus: ConnectionStatus, device1: Any?) {
            activity?.runOnUiThread(Runnable {
                if (ActivityCompat.checkSelfPermission(
                        activity!!,
                        Manifest.permission.BLUETOOTH_CONNECT
                    ) == PackageManager.PERMISSION_GRANTED
                ) {
                    val device = device1 as BluetoothDevice?
                    if (connectionStatus == ConnectionStatus.CONNECTED) {
                        remoteBTName = ""
                        remoteBTAdd = ""

                        remoteBTName = device!!.name
                        remoteBTAdd = device.address
                        Log.e(TAG, String.format("%s(%s)\nconnected", remoteBTName, remoteBTAdd))
                        if (shouldShowDisconnected()) {
                            ToastUtils.showShort(R.string.connect_success)
                        }
                        timeCountCur = SPUtils
                            .getInstance().getLong(Constants.DISCONNECT_TIME, 0)
                        if (timeCountCur > 0) {
                            startDisconnectTimer(timeCountCur)
                        } else {
                            formatConnectButton(timeCountCur)
                        }

                        // 保存已链接记录
                        if (!TextUtils.isEmpty(remoteBTAdd)) {
                            saveConnectedDevice(remoteBTAdd, remoteBTName)
                        }
                        mIsActiveDisconnect = false
                        mReConnectCount = RECONNECT_NUM
                    } else if (connectionStatus == ConnectionStatus.DISCONNECTED) {
//                    isKeyDownUP = false
                        cancelDisconnectTimer()
                        formatConnectButton(timeCountCur)
                        if (device != null) {
                            remoteBTName = device.name
                            remoteBTAdd = device.address
                            //                            if (shouldShowDisconnected())
                            Log.e(
                                TAG,
                                String.format(
                                    "%s(%s)\ndisconnected",
                                    remoteBTName,
                                    remoteBTAdd
                                )
                            )

                        } else {
                            onRfidEventsListener?.onRfidDisConnected()
                        }
                        ToastUtils.showShort(R.string.disconnect)
                        val reconnect: Boolean = SPUtils.getInstance()
                            .getBoolean(Constants.AUTO_RECONNECT, false)
                        if (mDevice != null && reconnect) {
                            reConnect(mDevice!!.address) // 重连
                        }
                    }
                    for (iConnectStatus in connectStatusList) {
                        iConnectStatus.getStatus(connectionStatus)
                    }
                }

            })
        }
    }

    inner class DisconnectTimerTask : TimerTask() {
        override fun run() {
            Log.e(TAG, "timeCountCur = $timeCountCur")
            val msg: Message =
                mHandler.obtainMessage(RUNNING_DISCONNECT_TIMER, timeCountCur)
            mHandler.sendMessage(msg)
            if (isScanning) {
                resetDisconnectTime()
            } else if (timeCountCur <= 0) {
                disconnect(true)
            }
            timeCountCur -= period
        }
    }
}